# !/usr/bin/python
# -*- coding: utf-8 -*-
from PyQt5 import QtGui
import configparser
import threading
import inspect
import ctypes
import win32api, win32con
from modbus_tk import modbus_tcp as mt
import matplotlib
import multiprocessing
import os
import sys
from PyQt5.Qt import *
from dym_plot import Ui_MainWindow
from mpl_plot import Mplplot
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
from data import mythread1
from ps import mythread_ps

matplotlib.use("Qt5Agg")

def _async_raise(tid, exctype):
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")
def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)


class Window(QMainWindow, Ui_MainWindow):

    def __init__(self, app):
        super(QMainWindow, self).__init__()
        self.app = app
        self.setup_ui()  # 渲染画布
        self.calibration_1 = []
        self.lineEdit_14.setText("0.2")
        self.i = 0
        self.master = None
        self.drawPaint = None
        # 参数相关事件
        # 当读取参数按钮被点击后调用setButton方法
        # self.setButton_2.clicked.connect(self.setButton_get)
        # 当设置按钮被点击后调用setButton方法
        self.setButton.clicked.connect(self.setButton_0)

        # 连接设备按钮connectButton_0
        self.connectButton.clicked.connect(self.connectButton_0)
        # 设备断开
        self.offButton.clicked.connect(self.offButton_0)

        # 读取串口数据
        self.readButton.clicked.connect(self.readButton_1)

        self.setButton_7.clicked.connect(self.setButtons_7)

        # 查看PS 曲线
        self.setButton5.clicked.connect(self.setButton_5)

        self.lineEdit_8.setText("10.10.100.254")
        self.lineEdit_9.setText("8899")

        # 下载全部数据调用self.downloadExcal()

        self.comboBox_2.currentTextChanged.connect(self.setButton_get)
        self.setButton_get()

        self.lineEdit.setEnabled(False)
        self.lineEdit_2.setEnabled(False)
        self.lineEdit_3.setEnabled(False)
        self.lineEdit_4.setEnabled(False)

        self.Box0.setChecked(True)

        self.Box0.stateChanged.connect(self.checkBox0)
        self.Box1.setChecked(True)
        self.Box1.stateChanged.connect(self.checkBox1)
        self.Box2.setChecked(True)
        self.Box2.stateChanged.connect(self.checkBox2)
        self.Box3.setChecked(True)
        self.Box3.stateChanged.connect(self.checkBox3)
        self.mythread = None

    def setup_ui(self):
        self.setupUi(self)
        self.phase_fig = Mplplot(width=5, height=3, dpi=72)
        # 加载相位振动波形
        self.fig_ntb = NavigationToolbar(self.phase_fig, self)
        self.gridlayout = QGridLayout(self.plot_view)
        self.gridlayout.addWidget(self.phase_fig)
        self.gridlayout.addWidget(self.fig_ntb)
        self.phase_fig.toolbar.setVisible(False)
        # 准备数据，绘制曲线
        self.phase_fig.add_line()

    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
        if self.drawPaint !=None:
            stop_thread(self.drawPaint)
        sys.exit(0)

    def ip_judge(self,ip_str):
        ip_list = ip_str.split(".")  # 将字符串按点分割成列表
        flag = True
        for num in ip_list: 
            if len(ip_list) == 4 and num.isdigit() and 0 <= int(num) <= 255:
                continue
            else:
                flag = False
                break
        if flag:
            return True
        else:
            return False

    def connectButton_0(self):
        try:
            if self.ip_judge(self.lineEdit_8.text()) and self.lineEdit_9.text()!="":
                # 设定串口为从站
                self.master = mt.TcpMaster(str(self.lineEdit_8.text()), int(self.lineEdit_9.text()))
                self.master.set_timeout(5.0)
                self.master.set_verbose(True)
                self.lineEdit_8.setEnabled(False)
                self.lineEdit_9.setEnabled(False)
                win32api.MessageBox(0, "已连接", "提示:", win32con.MB_OK)
            else:
                win32api.MessageBox(0, "请输入链接信息", "提示：", win32con.MB_ICONWARNING)
        except Exception as exc:
            win32api.MessageBox(0, str(exc), "提示:", win32con.MB_OK)

    def connectButton_1(self):
        t2 = threading.Thread(target=self.connectButton_1)
        t2.daemon = True
        t2.start()

    def checkBox0(self):
        self.phase_fig.curveControl(1, self.Box0.isChecked())
        # self.phase_fig.draw()

    def checkBox1(self):
        self.phase_fig.curveControl(2, self.Box1.isChecked())
        # self.phase_fig.draw()

    def checkBox2(self):
        self.phase_fig.curveControl(3, self.Box2.isChecked())
        # self.phase_fig.draw()

    def checkBox3(self):
        self.phase_fig.curveControl(4, self.Box3.isChecked())
        # self.phase_fig.draw()

    def offButton_0(self):  # 关闭串口
        if None != self.master:
            self.setButtons_7()
            self.master.close()
            self.lineEdit_8.setEnabled(True)
            self.lineEdit_9.setEnabled(True)
            win32api.MessageBox(0, "设备已断开", "提示:", win32con.MB_OK)
        else:
            win32api.MessageBox(0, "未开启连接", "提示：", win32con.MB_ICONWARNING)
        # print("执行了")

    def setButton_get(self):  # 读取方程系数

        fp_dir = os.getcwd()  # 取得的是exe文件路径
        path = os.path.join(fp_dir, "config.ini")  # 拼接上配置文件名称目录

        config = configparser.ConfigParser()
        config.read(path,encoding="utf-8")  # 读取配置文件采用绝对路径

        calibration = self.comboBox_2.currentText()
        items = config.items(calibration)
        self.lineEdit_5.setText(str(items[0][1]))
        self.lineEdit_6.setText(str(items[1][1]))
        self.lineEdit_7.setText(str(items[2][1]))

        self.calibration_1.append(float(items[0][1]))
        self.calibration_1.append(float(items[1][1]))
        self.calibration_1.append(float(items[2][1]))

        items1 = config.items("通道1")
        self.calibration_1.append(float(items1[0][1]))
        self.calibration_1.append(float(items1[1][1]))
        self.calibration_1.append(float(items1[2][1]))

        items2 = config.items("通道2")
        self.calibration_1.append(float(items2[0][1]))
        self.calibration_1.append(float(items2[1][1]))
        self.calibration_1.append(float(items2[2][1]))

        items3 = config.items("通道3")
        self.calibration_1.append(float(items3[0][1]))
        self.calibration_1.append(float(items3[1][1]))
        self.calibration_1.append(float(items3[2][1]))

    def setButton_0(self):  # 设置方程系数
        coefficient = ["a", "b", "c"]
        curpath = os.path.dirname(os.path.realpath(__file__))
        cfgpath = os.path.join(curpath, "config.ini")
        # 创建管理对象
        config = configparser.ConfigParser()

        # 先读出来
        config.read(cfgpath, encoding="utf-8")
        # 读取当前选择通道
        calibration = self.comboBox_2.currentText()
        # 读取标定系数
        calibration_data = []
        a = self.lineEdit_5.text()
        calibration_data.append(a)
        b = self.lineEdit_6.text()
        calibration_data.append(b)
        c = self.lineEdit_7.text()
        calibration_data.append(c)
        # 修改section里面的值
        for i, p in enumerate(coefficient):
            config.set(calibration, p, calibration_data[i])
        config.write(open(cfgpath, "r+", encoding="utf-8"))  # r+模式
        win32api.MessageBox(0, "参数设置成功", "提示:", win32con.MB_OK)

    def downloadExcal(self):  # 点击下载
        self.phase_fig.downloadExcal(0)

    #停止
    def setButtons_7(self):
        if self.readButton.text() == "暂停":
            self.readButton.setText("读取")
            if self.drawPaint != None:
                stop_thread(self.drawPaint)
                self.drawPaint = None
            self.phase_fig.i = 0
            self.phase_fig.y_data1 = []
            self.phase_fig.y_data2 = []
            self.phase_fig.y_data3 = []
            self.phase_fig.y_data4 = []
            self.phase_fig.x_data1 = []
            self.phase_fig.x_data2 = []
            self.phase_fig.x_data3 = []
            self.phase_fig.x_data4 = []
            self.lineEdit.setText("")
            self.lineEdit_2.setText("")
            self.lineEdit_3.setText("")
            self.lineEdit_4.setText("")
            self.comboBox_6.setEnabled(True)
            self.comboBox_7.setEnabled(True)
            self.lineEdit_14.setEnabled(True)
            self.comboBox_5.setEnabled(True)
            self.comboBox_3.setEnabled(True)
            if self.my_Thread != None:
                self.mythread.terminate()
                self.mythread = None
                stop_thread(self.my_Thread)
            self.phase_fig.clearPage()
            win32api.MessageBox(0, "程序已重置", "提示:", win32con.MB_OK)
            self.downloadExcal()
        else:
            win32api.MessageBox(0, "还未读取数据", "提醒", win32con.MB_ICONWARNING)

    def readButton_1(self):  # 读取串口数据
        if self.readButton.text() == "读取":
            if None != self.master:
                self.readButton.setText("暂停")
                self.comboBox_6.setEnabled(False)
                self.comboBox_7.setEnabled(False)
                self.lineEdit_14.setEnabled(False)
                self.comboBox_5.setEnabled(False)
                self.comboBox_3.setEnabled(False)
                curpath = os.path.dirname(os.path.realpath(__file__))
                cfgpath = os.path.join(curpath, "config.ini")

                # 实例化对象
                config = configparser.ConfigParser()
                if len(self.phase_fig.x_data1)>0:
                    self.i = self.phase_fig.x_data1[len(self.phase_fig.x_data1)-1]
                # 读ini文件
                config.read(cfgpath, encoding="utf-8")
                self.mythread = multiprocessing.Process(target=mythread1,args=(self.calibration_1,float(self.lineEdit_14.text()),self.i,self.master))
                self.mythread.start()

                self.my_Thread = self.phase_fig.my_Thread(self, float(self.lineEdit_14.text()))
                self.my_Thread.start()
                # #
                self.drawPaint = self.phase_fig.drawPaint(self, float(self.lineEdit_14.text()))
                self.drawPaint.start()
            else:
                win32api.MessageBox(0, "请开启链接", "提醒",win32con.MB_ICONWARNING)

        else:
            # 停止线程
            self.readButton.setText("读取")

            self.phase_fig.i = self.phase_fig.i + 1
            # self.phase_fig.downloadExcal(len(self.phase_fig.x_data1))
            if self.my_Thread != None:
                self.mythread.terminate()
                self.mythread = None
                stop_thread(self.my_Thread)
                self.my_Thread = None
            if self.drawPaint != None:
                stop_thread(self.drawPaint)
                self.drawPaint = None

    # 查看ps曲线
    def setButton_5(self):
        if len(self.phase_fig.y_data1)>0:
            self.mythreadPs = multiprocessing.Process(target=mythread_ps,args=(self.phase_fig.y_data1,self.phase_fig.y_data2,self.phase_fig.y_data3,self.phase_fig.y_data4,float(self.lineEdit_14.text()),self.calibration_1))
            self.mythreadPs.start()
        else:
            win32api.MessageBox(0, "请获取数据", "提醒", win32con.MB_ICONWARNING)


def main():
    app = QApplication(sys.argv)
    mywindow = Window(app)
    mywindow.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    multiprocessing.freeze_support()
    main()

